Python

As a start, I chose to use python because I thought I could use Niel's python program term.py to display a signal from an infrared remote control. The circuit is the same as the one used in the input week.

Coding

First of all, I had to reprogram the micro-controller to allow it to analyze the signal that it is recieving from the infrared device and decide which button was pressed and output it to the Rx pin through an ftdi cable. In order to do that, I have manually checked which part of the signal differentiates between each button. This part required several hours and causes eye strain especially because the output signal contained an 1520 bit array consisting of 0s and 1s and they contain a small amount of Bit Error Rate.

Microcontroller code

Part 1

This part includes the libraries, defines the input and output ports and pins, and the bit delays for 9600 baud rate. This part of the code was made by the help of Niel's codes
#include <avr/io.h>
#include <util/delay.h>

#define output(directions,pin) (directions |= pin) // set port direction for output
#define input(directions,pin) (directions &= (~pin)) // set port direction for input
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
#define bit_delay_time 102 // bit delay for 9600 with overhead
#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay

#define input_port PORTA
#define input_direction DDRA
#define input_pin (1 << PA3)
#define input_pins PINA
#define serial_port PORTA
#define serial_direction DDRA
#define serial_pin_out (1 << PA1)

Part 2

This part was fully taken from Niel, which is a void function which can be called and used to output a character via the pin stated, as a serial signal. The function requires three parameters: the serial port, output pin and the output character.
void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
   //
   // send character in txchar on port pin
   //    assumes line driver (inverts bits)
   //
   // start bit
   //
   clear(*port,pin);
   bit_delay();
   //
   // unrolled loop to write data bits
   //
   if bit_test(txchar,0)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,1)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,2)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,3)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,4)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,5)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,6)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,7)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   //
   // stop bit
   //
   set(*port,pin);
   bit_delay();
   //
   // char delay
   //
   bit_delay();
   }

Part 3 - main

Calibrating the clock speed so the delays run for the actual time stated.
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);

Initializing the input and output pins
set(serial_port, serial_pin_out);
   output(serial_direction, serial_pin_out);
   set(input_port, input_pin); // turn on pull-up
   input(input_direction, input_pin);

Initializing the variables
	DDRA |= 0b10000000;
	double V;
	int A[94];
	int pos;
	unsigned int flag;
	unsigned int i = 0;
	int S;

Checks if there is a signal from the IR sensor. If it does, then the signal is saved for 0.076seconds in the rate of 20kHz in the form of an array consisting of 0s and 1s into A. Then the signal is analyzed and the pressed button number (only for 1, 2 and 3) is outputted to the Rx pin in the form of a character.
		if (V < 2){
				for ( i = 0; i < 95	; i++ ){
				A[i] = 0;}
			for(i = 0;i<1520;i++){
				V = PINA & 1<<PA2;
				if (V < 2){
					PORTA |= 0b10000000;
      		index = i/16;
	     		pos = i%16; 
					flag = 1;   
	    		flag = flag << pos;
	      	A[index] = A[index] | flag; 
					_delay_us(50); 
				}
				else{
					PORTA &= ~(0b10000000);
       		index = i/16;
       		pos = i%16; 
      		flag = 1;   
    		flag = flag << pos;
					flag = ~flag;
     		A[index] = A[index] & flag;
					_delay_us(50);
				}
			}
					if (A[43]==0 & A[48]!=0){	
					put_char(&serial_port, serial_pin_out, '2');_delay_ms(1000);
				}
		if (A[43]==-256){
				put_char(&serial_port, serial_pin_out, '1');_delay_ms(1000);
				}
		if (A[43]==0 & A[48]==0 & A[0]==-1){	
					put_char(&serial_port, serial_pin_out, '3');_delay_ms(1000);
				}
			_delay_ms(2000);
		}
		
		PORTA &= ~(0b10000000);

term.py

#!/usr/bin/env python
#
# term.py
#
# term.py serial_port port_speed
#
# Neil Gershenfeld
# CBA MIT 7/27/07
#
# (c) Massachusetts Institute of Technology 2007
# This work may be reproduced, modified, distributed,
# performed, and displayed for any purpose. Copyright is
# retained and must be preserved. The work is provided
# as is; no warranty is provided, and users accept all 
# liability.
#

import sys,time,serial
from Tkinter import *
from select import *

NROWS = 40
NCOLS = 16

def key(event):
   #
   # key press event handles
   #
   key = event.char
   #print 'send',ord(key)
   if (ord(key) == 13):
      key = chr(10)
   ser.write(key)

def quit():
   #
   # clean up and quit
   #
   sys.exit()

def idle(parent):
   #
   # idle loop
   #
   wait = ser.inWaiting()
   if (wait != 0):
      #
      # read character
      #
      byte = ser.read()
      widget_text.config(state=NORMAL)
      #print byte,ord(byte)
      if (ord(byte) == 10):
         #
	 # CR
	 #
	 widget_text.insert(INSERT,'\n')
	 if (int(float(widget_text.index(END))) > (NROWS+1)):
	    widget_text.delete(1.0,2.0)
      #if (ord(byte) == 13):
         #
	 # CR
	 #
	 #widget_text.insert(INSERT,'\n')
	 #if (int(float(widget_text.index(END))) > (NROWS+1)):
	 #   widget_text.delete(1.0,2.0)
      elif (byte == 8):
         #
         # BS
         #
         widget_text.delete(INSERT+"-1c",INSERT)
      else:
         #
         # character
         #
         widget_text.insert(INSERT,byte)
      widget_text.config(state=DISABLED)
   time.sleep(0.001)
   parent.after_idle(idle,parent)

#
#  check command line arguments
#
if (len(sys.argv) != 3):
   print "command line: term.py serial_port speed"
   sys.exit()
port = sys.argv[1]
speed = int(sys.argv[2])
#
# open serial port
#
ser = serial.Serial(port,speed)
ser.parity=serial.PARITY_NONE
ser.setDTR()
#
# flush buffers
#
ser.flushInput()
ser.flushOutput()
#
# set up UI
#
root = Tk()
root.bind('',key)
root.title('term.py')
#
widget_quit = Button(root, text="quit",command=quit)
widget_quit.pack()
#
address_frame = Frame(root)
Label(address_frame,text="port: "+port).pack(side='left')
Label(address_frame,text="  speed: "+str(speed)).pack(side='left')
address_frame.pack()
#
widget_text = Text(root, bg='white', bd=5, width=NCOLS, height=NROWS, font=('arial',10,'bold'))
#widget_text.bind('',key)
widget_text.config(state=DISABLED)
widget_text.pack()
#
# begin event loop
#
root.after(100,idle,root)
root.mainloop()
Term.py was used to check what specifies which button was pressed from the remote control. The images below show a part of the code sent from the remote when buttons 1 and 2 are pressed.It can be noticed that the changes start to appear after the 11th line.

1 code 2 code




https://github.com/pyserial/pyserial/blob/master/documentation/pyserial.rst#installation http://pypi.python.org/pypi/pyserial python3 setup.py install Open port at “9600,8,N,1”, no timeout: >>> import serial >>> ser = serial.Serial('/dev/ttyUSB0') # open serial port >>> print(ser.name) # check which port was really used >>> ser.write(b'hello') # write a string >>> ser.close() # close port instrument control package https://octave.sourceforge.io/download.php?package=instrument-control-0.3.0.tar.gz steps for installing package https://octave2work.blogspot.com/2017/03/new-package-installation-steps.html Reading serial data https://www.edn.com/design/analog/4440674/Read-serial-data-directly-into-Octave

code

#include <avr/io.h>
#include <util/delay.h>

#define output(directions,pin) (directions |= pin) // set port direction for output
#define input(directions,pin) (directions &= (~pin)) // set port direction for input
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
#define bit_delay_time 102 // bit delay for 9600 with overhead
#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay

#define input_port PORTA
#define input_direction DDRA
#define input_pin (1 << PA3)
#define input_pins PINA
#define serial_port PORTA
#define serial_direction DDRA
#define serial_pin_out (1 << PA1)

void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
   //
   // send character in txchar on port pin
   //    assumes line driver (inverts bits)
   //
   // start bit
   //
   clear(*port,pin);
   bit_delay();
   //
   // unrolled loop to write data bits
   //
   if bit_test(txchar,0)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,1)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,2)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,3)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,4)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,5)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,6)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,7)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   //
   // stop bit
   //
   set(*port,pin);
   bit_delay();
   //
   // char delay
   //
   bit_delay();
   }

int main(void) {
   //
   // main
   //
   // set clock divider to /1
   //
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
   //
   // initialize pins
   //
   set(serial_port, serial_pin_out);
   output(serial_direction, serial_pin_out);
   set(input_port, input_pin); // turn on pull-up
   input(input_direction, input_pin);
   //
   // main loop
   //
		



	DDRA |= 0b10000000;
	double V;
	int A[94];
	int pos;
	unsigned int flag;
	unsigned int i = 0;
	int S;




   while (1) {
			
		V = PINA & 1<<PA2;
		int index = 0;
		
			for ( i = 0; i < 95	; i++ ){
				A[i] = 0;}
		if (V < 1){
			for(i = 0;i<1520;i++){
				V = PINA & 1<<PA2;
				if (V < 1){
					PORTA |= 0b10000000;
      		index = i/16;
	     		pos = i%16; 
					flag = 1;   
	    		flag = flag << pos;
	      	A[index] = A[index] | flag; 
					_delay_us(50); 
				}
				else{
					PORTA &= ~(0b10000000);
       		index = i/16;
       		pos = i%16; 
      		flag = 1;   
    		flag = flag << pos;
					flag = ~flag;
     		A[index] = A[index] & flag;
					_delay_us(50);
				}
			}
					if (A[43]==0 & A[48]!=0){	
					put_char(&serial_port, serial_pin_out, '2');_delay_ms(1000);
				}
		if (A[43]==-256){
				put_char(&serial_port, serial_pin_out, '1');_delay_ms(1000);
				}
		if (A[43]==0 & A[48]==0 & A[0]==-1){	
					put_char(&serial_port, serial_pin_out, '3');_delay_ms(1000);
				}
			_delay_ms(2000);
		}
		
		PORTA &= ~(0b10000000);
		
		/*S = PINA & 1<<PA3;
		if (S < 1){	
			for(i = 0;i<1520;i++){
				index = i/16;
				pos = i%16;
				flag = 1;
				flag = flag << pos;
				flag = ~flag;
				if ( ~(A[index] | flag) == 0 ){
					PORTA |= 0b10000000;
					_delay_us(500);
					put_char(&serial_port, serial_pin_out, '1');
				}
				else{
					PORTA &= ~(0b10000000);
					_delay_us(500);
					put_char(&serial_port, serial_pin_out, '0');
				}
			}
		}
		PORTA &= ~(0b10000000);*/
		
		/*S = PINA & 1<<PA3;
		if (S < 1){	
		if (A[43]==0 & A[48]!=0){	
					put_char(&serial_port, serial_pin_out, '2');_delay_ms(1000);
				}
		if (A[43]==-256){
				put_char(&serial_port, serial_pin_out, '1');_delay_ms(1000);
				}
		if (A[43]==0 & A[48]==0){	
					put_char(&serial_port, serial_pin_out, '3');_delay_ms(1000);
				}
		}*/



			//PORTA |= 0b10000000;put_char(&serial_port, serial_pin_out, 'd');_delay_ms(1058);
			//PORTA &= ~(0b10000000);put_char(&serial_port, serial_pin_out, 'u');_delay_ms(1058);
      //
      // wait for button down
      //
      /*while (0 != pin_test(input_pins,input_pin))
         ;
      put_char(&serial_port, serial_pin_out, 'd');
      //
      // wait for button up
      //
      while (0 == pin_test(input_pins,input_pin))
         ;
      put_char(&serial_port, serial_pin_out, 'u');*/
      }
   }
	





Result

bottom1

bottom1